#nullable enable
// ReSharper disable once CheckNamespace
namespace Fluent;

using System.Windows;
using System.Windows.Controls;
using Fluent.Internal.KnownBoxes;

/// <summary>
/// Represents KeyTip control
/// </summary>
public class KeyTip : Label
{
    #region Keys Attached Property

    /// <summary>
    /// Using a DependencyProperty as the backing store for Keys.
    /// This enables animation, styling, binding, etc...
    /// </summary>
    public static readonly DependencyProperty KeysProperty =
        DependencyProperty.RegisterAttached("Keys", typeof(string), typeof(KeyTip), new PropertyMetadata(OnKeysChanged));

    private static void OnKeysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    }

    /// <summary>
    /// Sets value of attached property Keys for the given element
    /// </summary>
    /// <param name="element">The given element</param>
    /// <param name="value">Value</param>
    public static void SetKeys(DependencyObject element, string? value)
    {
        element.SetValue(KeysProperty, value);
    }

    /// <summary>
    /// Gets value of the attached property Keys of the given element
    /// </summary>
    /// <param name="element">The given element</param>
    [System.ComponentModel.DisplayName("Keys")]
    [AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]
    [System.ComponentModel.Category("KeyTips")]
    [System.ComponentModel.Description("Key sequence for the given element")]
    public static string? GetKeys(DependencyObject element)
    {
        return (string?)element.GetValue(KeysProperty);
    }

    #endregion

    #region AutoPlacement Attached Property

    /// <summary>
    /// Using a DependencyProperty as the backing store for AutoPlacement.
    /// This enables animation, styling, binding, etc...
    /// </summary>
    public static readonly DependencyProperty AutoPlacementProperty =
        DependencyProperty.RegisterAttached("AutoPlacement", typeof(bool), typeof(KeyTip), new PropertyMetadata(BooleanBoxes.TrueBox));

    /// <summary>
    /// Sets whether key tip placement is auto
    /// or defined by alignment and margin properties
    /// </summary>
    /// <param name="element">The given element</param>
    /// <param name="value">Value</param>
    public static void SetAutoPlacement(DependencyObject element, bool value)
    {
        element.SetValue(AutoPlacementProperty, BooleanBoxes.Box(value));
    }

    /// <summary>
    /// Gets whether key tip placement is auto
    /// or defined by alignment and margin properties
    /// </summary>
    /// <param name="element">The given element</param>
    [System.ComponentModel.DisplayName("AutoPlacement")]
    [AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]
    [System.ComponentModel.Category("KeyTips")]
    [System.ComponentModel.Description("Whether key tip placement is auto or defined by alignment and margin properties")]
    public static bool GetAutoPlacement(DependencyObject element)
    {
        return (bool)element.GetValue(AutoPlacementProperty);
    }

    #endregion

    #region HorizontalAlignment Attached Property

    /// <summary>
    /// Using a DependencyProperty as the backing store for HorizontalAlignment.
    /// This enables animation, styling, binding, etc...
    /// </summary>
    public static new readonly DependencyProperty HorizontalAlignmentProperty =
        DependencyProperty.RegisterAttached(nameof(HorizontalAlignment), typeof(HorizontalAlignment), typeof(KeyTip), new PropertyMetadata(HorizontalAlignment.Center));

    /// <summary>
    /// Sets Horizontal Alignment of the key tip
    /// </summary>
    /// <param name="element">The given element</param>
    /// <param name="value">Value</param>
    public static void SetHorizontalAlignment(DependencyObject element, HorizontalAlignment value)
    {
        element.SetValue(HorizontalAlignmentProperty, value);
    }

    /// <summary>
    /// Gets Horizontal alignment of the key tip
    /// </summary>
    /// <param name="element">The given element</param>
    [System.ComponentModel.DisplayName("HorizontalAlignment")]
    [AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]
    [System.ComponentModel.Category("KeyTips")]
    [System.ComponentModel.Description("Horizontal alignment of the key tip")]
    public static HorizontalAlignment GetHorizontalAlignment(DependencyObject element)
    {
        return (HorizontalAlignment)element.GetValue(HorizontalAlignmentProperty);
    }

    #endregion

    #region VerticalAlignment Attached Property

    /// <summary>
    /// Gets vertical alignment of the key tip
    /// </summary>
    /// <param name="element">The given element</param>
    [System.ComponentModel.DisplayName("VerticalAlignment")]
    [AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]
    [System.ComponentModel.Category("KeyTips")]
    [System.ComponentModel.Description("Vertical alignment of the key tip")]
    public static VerticalAlignment GetVerticalAlignment(DependencyObject element)
    {
        return (VerticalAlignment)element.GetValue(VerticalAlignmentProperty);
    }

    /// <summary>
    /// Sets vertical alignment of the key tip
    /// </summary>
    /// <param name="obj">The given element</param>
    /// <param name="value">Value</param>
    public static void SetVerticalAlignment(DependencyObject obj, VerticalAlignment value)
    {
        obj.SetValue(VerticalAlignmentProperty, value);
    }

    /// <summary>
    /// Using a DependencyProperty as the backing store for VerticalAlignment.
    /// This enables animation, styling, binding, etc...
    /// </summary>
    public static new readonly DependencyProperty VerticalAlignmentProperty =
        DependencyProperty.RegisterAttached(nameof(VerticalAlignment), typeof(VerticalAlignment), typeof(KeyTip), new PropertyMetadata(VerticalAlignment.Center));

    #endregion

    #region Margin Attached Property

    /// <summary>
    /// Gets margin of the key tip
    /// </summary>
    /// <param name="obj">The key tip</param>
    /// <returns>Margin</returns>
    [System.ComponentModel.DisplayName("Margin")]
    [AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]
    [System.ComponentModel.Category("KeyTips")]
    [System.ComponentModel.Description("Margin of the key tip")]
    public static Thickness GetMargin(DependencyObject obj)
    {
        return (Thickness)obj.GetValue(MarginProperty);
    }

    /// <summary>
    /// Sets margin of the key tip
    /// </summary>
    /// <param name="obj">The key tip</param>
    /// <param name="value">Value</param>
    public static void SetMargin(DependencyObject obj, Thickness value)
    {
        obj.SetValue(MarginProperty, value);
    }

    /// <summary>
    /// Using a DependencyProperty as the backing store for Margin.
    /// This enables animation, styling, binding, etc...
    /// </summary>
    public static new readonly DependencyProperty MarginProperty =
        DependencyProperty.RegisterAttached(nameof(Margin), typeof(Thickness), typeof(KeyTip), new PropertyMetadata(default(Thickness)));

    #endregion

    static KeyTip()
    {
        // Override metadata to allow styling
        DefaultStyleKeyProperty.OverrideMetadata(typeof(KeyTip), new FrameworkPropertyMetadata(typeof(KeyTip)));
    }
}